package com.gc.cscott.cli;

import com.gc.cscott.domain.Executable;
import com.gc.cscott.domain.Solution;
import com.gc.cscott.domain.contest.Contest;
import com.gc.cscott.fs.FileSystemWorker;
import com.gc.cscott.domain.Competitor;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.apache.commons.io.FileUtils;

/**
 *
 * @author root
 */
public class SeparateCompetitorsByLanguageCommand implements Command {
    @Inject
    Contest contest;

    @Inject
    FileSystemWorker fsWorker;

    public List<String> listHelp() {
        return ImmutableList.of(
                "Rearranges competitors's directories grouping",
                "them by used programming language.",
                "If more than one language is used by competitor",
                "It will be placed into 'wired' directory.",
                "If programming language is not recognized",
                "then solutions will be placed into",
                "'unknown' directory. If no solutions - to 'empty' directory.",
                "Required argument:",
                "<dst> - destination directory");
    }

    public List<String> perform(List<String> args) {
        LinkedList<String> mutableArgs = new LinkedList<String>(args);
        if (mutableArgs.isEmpty()) {
            throw new Error("Missed argument - destination directory");
        } else {
            String destinationPath = mutableArgs.removeFirst();
            if (destinationPath.startsWith("-") == true) {
                throw new Error("Destination path name mixed with command name. Eliminate '-' from the start of the path");
            }

            File destinationDir = new File(destinationPath);
            if (destinationDir.exists() == true) {
                throw new Error("path already exists, can no overwrite: " + destinationDir.getAbsolutePath());
            }

            try {
                System.out.println("Separating competitors:");
                List<Competitor> competitorsList = fsWorker.listCompetitorsAll();
                final int longestName = ReportUtils.longestName(competitorsList);
                for (Competitor competitor : competitorsList) {
                    System.out.printf("  %-"+(longestName+1)+"s, action: ", competitor.getName());
                    Set<String> languagesSet = new HashSet<String>();
                    for (Solution solution : fsWorker.listSolutions(competitor)) {
                        try {
                            Executable executable = fsWorker.findSourceInSolution(solution);
                            languagesSet.add(executable.getPlatform().getName());
                        } catch (FileNotFoundException ex) {
                            //unrecognizd solution of empty solution folder. move to unknown.
                            languagesSet.add("_unknown");
                        }
                    }
                    if (languagesSet.isEmpty() == true) {
                        System.out.println("-> empty");
                        File destinationGroupDir = new File(new File(destinationDir, "_empty"), competitor.getName());
                        FileUtils.copyDirectory(competitor.getBasedir(), destinationGroupDir);
                    } else if (languagesSet.size()==1){
                        String languageName=Iterables.getOnlyElement(languagesSet).toLowerCase();
                        System.out.println("-> "+languageName);
                        File destinationGroupDir = new File(new File(destinationDir, languageName), competitor.getName());
                        FileUtils.copyDirectory(competitor.getBasedir(), destinationGroupDir);
                    } else {
                        System.out.println("-> wired");
                        File destinationGroupDir = new File(new File(destinationDir, "_wired"), competitor.getName());
                        FileUtils.copyDirectory(competitor.getBasedir(), destinationGroupDir);
                    }
                }
            } catch (IOException e) {
                throw new Error(e);
            }
        }

        return ImmutableList.copyOf(mutableArgs);
    }
}
